using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Xml;
using System.IO;
/*
	ToDo: review which of these are still used!
*/
namespace DbView
{
    /// <summary>
    /// Summary description for Helper.
    /// </summary>
    public class Helper
    {
        public Helper() { }

        // this one mainly for Xml
        public static string FormatLongCellDataForDisplay(String data)
        {
            if (data.IndexOf("<") != -1 && data.IndexOf(">") != -1) // might be Xml
            {
                try
                {
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(data);
                    data = FormatXML(doc);
                }
                catch (SystemException exc)
                {
                    string message = exc.Message;
                }
            }
            return data;
        }

        // new 2011 Xml Helper
        public static string FormatXML(XmlDocument doc)
        {
            // Create a stream buffer that can be read as a string
            using (StringWriter sw = new StringWriter())

            // Create a specialized writer for XML code
            using (XmlTextWriter xtw = new XmlTextWriter(sw))
            {
                // Set the writer to use indented (hierarchical) elements
                xtw.Formatting = System.Xml.Formatting.Indented;

                // Write the XML document to the stream
                doc.WriteTo(xtw);

                // Return the stream as a string
                return sw.ToString();
            }
        }

        public static int GetSelectedRow(DataGridView results, out DataRow selectedRow)
        {
            // DataGridViewRow relates to DataGridView
            DataGridViewRow current = results.CurrentRow;
            // Detect right-click in the edit buffer.
            selectedRow = null;
            if (current == null) return -1;
            if (current.DataBoundItem == null) return -1;

            // this is related to a view of the data via the DataBoundItem prop.
            DataRowView rv = (DataRowView)current.DataBoundItem;
            selectedRow = rv.Row;
            BindingSource bSource = (BindingSource)results.DataSource;
            DataTable dt = (DataTable)bSource.DataSource;
            for (int idx2 = 0; idx2 < dt.Rows.Count; ++idx2)
                if (dt.Rows[idx2] == selectedRow)
                    return idx2;
            return 0;
        }

		// Specialised helper method to convert a sql wild card search to a regex pattern
		public static string SqlToRegex(string sqlPattern, bool wantNumericExact)
		{
			// make numeric searches spot on
			if (wantNumericExact)
			{
				int i;
				if (int.TryParse(sqlPattern, out i))
				{
					// yes it was an int
					return "^" + sqlPattern + "$"; // regex for an exact match
				}
			}
			sqlPattern = RegexEscapeControlChars(sqlPattern);
			// abc -> abc
			if (!sqlPattern.Contains("%")) return sqlPattern; // nothing to do
			if (sqlPattern == "%") return "";  // wild
			// Abc% -> ^Abc
			// %Abc -> Abc$
			// %Abc% -> Abc
			// %abc%def% -> abc.*?def
			// abc%def% -> ^abc.*?def
			// abc%def -> ^abc%def  due to special logic elsewhere
			// if ends with % remove that add ^ to the start
			// if starts with % remove that add $ to the end
			// if contains % then replace with .*?
			
			// find wild cards
			bool starts = sqlPattern.IndexOf('%') == 0;
			bool ends = sqlPattern.LastIndexOf('%') == sqlPattern.Length -1;

			// trim the SQL wildcard tokens off
			if (starts) sqlPattern = sqlPattern.Substring(1);
			if (ends) sqlPattern = sqlPattern.Substring(0, sqlPattern.Length - 1);
			
			// add appropriate Regex start and end anchors unless both ends were tokenised with 
			// %. eg %ABC%
			if (!(starts && ends)) // same as text anywhere search
				sqlPattern = ((ends) ? "^" : "") + sqlPattern + ((starts) ? "$" : "");
			
			// test whether a % was in the middle somewhere
			if (sqlPattern.Contains("%")) 
			{
				// test below treats A%C as must start with A then anything then C
				if (!ends) sqlPattern = "^" + sqlPattern;
				// % in the middle treated as any length pattern
				sqlPattern = sqlPattern.Replace("%", ".*?");
			}
			return sqlPattern;
		}

		private static string RegexEscapeControlChars(string tgt)
		{
			// probably not all yet. Add 
			return tgt.Replace("\\", @"\\") // This must be first
					.Replace(".", @"\.")
					.Replace("(", @"\(")
					.Replace(")", @"\)")
					.Replace("^", @"\^")
					.Replace("$", @"\$")
					.Replace("*", @"\*")
					.Replace("]", @"\]")
					.Replace("[", @"\[");
		}

    }
}
